﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace Air_condition.DO
{
    [Serializable]
    class Room : ICloneable
    {
        //  instance the vars for room
        private double dbinsideTemperature;
        private double dbinsideVaporContains;
        private double dboutsideVaporContains;
        private double dbwidth;
        private double dboutsideTemperature;
        private int ilocation;

        public int iLocation
        {
            get { return ilocation; }
            set { ilocation = value; }
        }
        private double soutsideActiveAir;
        private int ispaceConditioning;

        public int iSpaceConditioning
        {
            get { return ispaceConditioning; }
            set { ispaceConditioning = value; }
        }

      

        public double sOutsideActiveAir
        {
            get { return soutsideActiveAir; }
            set { soutsideActiveAir = value; }
        }


        public double dbOutsideTemperature
        {
            get { return dboutsideTemperature; }
            set { dboutsideTemperature = value; }
        }

        public double dbWidth
        {
            get { return dbwidth; }
            set { dbwidth = value; }
        }
        private double dbheigh;

        public double dbHeigh
        {
            get { return dbheigh; }
            set { dbheigh = value; }
        }
        private double dblength;

        public double dbLength
        {
            get { return dblength; }
            set { dblength = value; }
        }
        private double dbvolume;
        private double dbstandardAir;
        private double dbairCoefficient;
        private string sname;
        private int itype;
        public InternalLoad inter = new InternalLoad();
        public Glass gl = new Glass();
        public Weather we = new Weather();
        //public Roof ro = new Roof();
        public List<Construction> lConstruction = new List<Construction>();
        public Result res = new Result();

        public double dbAirCoefficient
        {
            get { return dbairCoefficient; }
            set { dbairCoefficient = value; }
        }

        //  set/get the temperture
        public double dbInsideTemperature
        {
            get { return dbinsideTemperature; }
            set { dbinsideTemperature = value; }
        }
      
        //  set/get the volume
        public double dbVolume
        {
            get { return dbvolume; }
            set { dbvolume = value; }
        }

        //  set/get the name
        public string sName
        {
            get { return sname; }
            set { sname = value; }
        }
        //  set/get the type
        public int iType
        {
            get { return itype; }
            set { itype = value; }
        }

        public double dbInsideAirContainingLevel
        {
            get { return dbinsideVaporContains; }
            set { dbinsideVaporContains = value; }
        }

        public double dbOutsideAirContainingLevel
        {
            get { return dboutsideVaporContains; }
            set { dboutsideVaporContains = value; }
        }
        //
        
       #region ICloneable Members
      
      //public object Clone()
      //  {
      //      object clone;
      //      using (System.IO.MemoryStream stream = new MemoryStream())
      //      {
      //          BinaryFormatter formatter = new BinaryFormatter();
      //          // Serialize this object
      //          formatter.Serialize(stream, this);
      //          stream.Position = 0;
      //          // Deserialize to another object
      //          clone = formatter.Deserialize(stream);
      //      }
      //      return clone;
      //  }
        #endregion

        // Tổng nhiệt hiện của phòng bằng Qhf = (Q11 + Q12 + Q2 + Q31 + Q32 + Q33) phần 1.4.1 Sách

        public double CalculateSumRoomSensibleHeat()
        {
            double Q11 = gl.CalculateGlassRadiationHeat();
            res.dbGlassRadiationHeat = Q11;
            // Có cần tính cho nhiệt bức xạ qua mái ko?
            //double Q12 = ro.CalculateRoofRadiationHeat(we.dbOutSideTemperature, dbinsideTemperature);
            double Q2 = 0;
            foreach (Construction con in lConstruction){
                Q2 += con.CalculateConstructionHeatTransfer(we.dbOutSideTemperature, dbinsideTemperature);
            }
            res.dbSumConstructionHeatTransfer = Q2;
            double Q31 = inter.CalculatePeopleSensibletHeat();
            res.dbPeopleSensibleHeat = Q31;
            double Q32 = inter.CalculateLightSensibleHeat(dblength * dbwidth);
            res.dbLightSensibleHeat = Q32;
            double Q33 = inter.CalculatePowerToolsSensibleHeat();
            res.dbPowerToolsSensibleHeat = Q33;
            res.dbSumRoomSensibleHeat = Q11 + Q2 + Q31 + Q32 + Q33;
            //return Q11 + Q12 + Q2 + Q31 + Q32 + Q33 ;
            return Q11 + Q2 + Q31 + Q32 + Q33;
        }
       
        //  Nhiệt hiện do không khí ngoài trời chủ động đưa vào phòng QhN1
        public double CalculateOutSideAirActiveSensibleHeat()
        {
            //  dbairMountForOnePeople lấy từ library va inumberPeople user nhập từ giao diện
            //  dboutDoorTemperature lấy từ library phụ thuộc vào location, dbinsideTemperature user nhập từ giao diện
            dbstandardAir = inter.AirMountForOnePeople * inter.NumberPeople;
            res.dbOutSideAirActiveSensibleHeat = 1.23 * dbstandardAir * (we.dbOutSideTemperature - dbinsideTemperature);
            return 1.23 * dbstandardAir * (we.dbOutSideTemperature - dbinsideTemperature);
        }

        //  Nhiệt hiện do lượng không khí ngoài trời lọt qua khe cửa QhN2

        public double CalculateOutSideAirSensibleHeat()
        {
            //  dbvolume người dùng nhập từ giao diện, dbAirCoefficient lấy từ library
            //  dboutDoorTemperature lấy từ library phụ thuộc vào location, dbinsideTemperature user nhập từ giao diện
            res.dbOutSideAirSensibleHeat = 0.39 * dbvolume * dbairCoefficient * (we.dbOutSideTemperature - dbinsideTemperature);
            return 0.39 * dbvolume * dbairCoefficient * (we.dbOutSideTemperature - dbinsideTemperature);
        }
        // Tổng nhiệt hiện của không khí ngoài trời đưa vào phòng QhN = QhN1 + QhN2
      
        public double CalculateSumOutSideSensibleHeat()
        {
            double QhN1 = CalculateOutSideAirActiveSensibleHeat();
            double QhN2 = CalculateOutSideAirSensibleHeat();
            res.dbSumOutSideSensibleHeat = QhN1 + QhN2;
            return QhN1 + QhN2;
        }

        // Tổng nhiệt hiện Qh = Qhf + QhN
       
        public double CalculateSumSensibleHeat()
        {
            double Qhf = CalculateSumRoomSensibleHeat();
            double QhN = CalculateSumOutSideSensibleHeat();
            res.dbSumSensibleHeat = Qhf + QhN;
            return Qhf + QhN;
        }

        // Tổng nhiệt ẩn tỏa ra từ phòng Qaf
     
        public double CalculateSumRoomLatentHeat()
        {
            double Qaf = inter.CalculatePeopleLatentHeat();
            res.dbSumRoomLatentHeat = Qaf;
            return Qaf;
        }

        //  Nhiệt ẩn do không khí từ ngoài trời chủ động đưa vào phòng QaN1
       
        public double CalculateOutSideAirActiveLatentHeat()
        {

            //  dbairMountForOnePeople lấy từ library va inumberPeople user nhập từ giao diện
            //  dboutDoorVaporContains và dbroomvaporContains user nhập từ giao diện
            dbstandardAir = inter.AirMountForOnePeople * inter.NumberPeople;
            res.dbOutSideAirActiveLatentHeat = 3 * dbstandardAir * (dboutsideVaporContains - dbinsideVaporContains);
            return 3 * dbstandardAir * (dboutsideVaporContains - dbinsideVaporContains);
        }

        //  Nhiệt ẩn của không khí lọt vào phòng QaN2
     
        public double CalculateOutSideAirLatentHeat()
        {
            //  dbvolume người dùng nhập từ giao diện
            //  dboutDoorVaporContains và dbroomvaporContains user nhập từ giao diện
            res.dbOutSideAirLatentHeat = 0.84 * dbvolume * (dboutsideVaporContains - dbinsideVaporContains);
            return 0.84 * dbvolume * (dboutsideVaporContains - dbinsideVaporContains);
        }
        //  Tổng nhiệt ẩn của không khí ngoài trời đưa vào phòng QaN = QaN1 + QaN2
      
        public double CalculateSumOutSideLatentHeat()
        {
            double QaN1 = CalculateOutSideAirActiveLatentHeat();
            double QaN2 = CalculateOutSideAirLatentHeat();
            res.dbSumOutSideLatentHeat = QaN1 + QaN2;
            return QaN1 + QaN2;
        }

        //  Tổng nhiệt ẩn Qa = Qaf + QaN
   
        public double CalculateSumLatentHeat()
        {
            double Qaf = CalculateSumRoomLatentHeat();
            double QaN = CalculateSumOutSideLatentHeat();
            res.dbSumLatentHeat = Qaf + QaN;
            return Qaf + QaN;
        }

        //  Năng suất kho lạnh Qo = Qh + Qa
       
        public double CalculateColdProductivity()
        {
            double Qh = CalculateSumSensibleHeat();
            double Qa = CalculateSumLatentHeat();
            res.dbSumColdProductivity = Qh + Qa;
            return Qh + Qa;
        }

        public object Clone()
        {
            object clone;
            try
            {
                using (MemoryStream stream = new MemoryStream())
                {

                    BinaryFormatter formatter = new BinaryFormatter();

                    // Serialize this object

                    formatter.Serialize(stream, this);

                    stream.Position = 0;

                    // Deserialize to another object

                    clone = formatter.Deserialize(stream);

                }
                return clone;
            }
            catch (Exception e)
            {
                return e;
            }

        }
    }
}
